﻿namespace KP_CommonLibrary.KP_CommonControls.NumericInput
{
   
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Runtime.CompilerServices;
    using KP_CommonLibrary.KP_CommonControls.NumericInput;

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class MaskProperties
    {
        private bool? fAllowNullInput;
        protected AutoCompleteType fAutoComplete;
        protected bool fBeepOnError;
        protected CultureInfo fCulture;
        protected string fEditMask;
        protected bool fIgnoreMaskBlank;
        protected KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType fMaskType;
        protected char fPlaceHolder;
        protected bool fSaveLiteral;
        protected bool fShowPlaceHolders;
        protected bool fUseMaskAsDisplayFormat;
        private int lockEvents;
       // protected internal RepositoryItemTextEdit RepositoryItem;

        public event EventHandler AfterChange;

        public event ChangeEventHandler BeforeChange;

        public MaskProperties()
        {
            this.fSaveLiteral = true;
            this.fShowPlaceHolders = true;
            this.fPlaceHolder = '_';
            this.fEditMask = string.Empty;
            this.fIgnoreMaskBlank = true;
        }

        public MaskProperties(MaskProperties data)
        {
            this.fSaveLiteral = true;
            this.fShowPlaceHolders = true;
            this.fPlaceHolder = '_';
            this.fEditMask = string.Empty;
            this.fIgnoreMaskBlank = true;
            this.Assign(data);
        }

        public void Assign(MaskData data)
        {
            this.BeginUpdate();
            try
            {
                this.fIgnoreMaskBlank = data.IgnoreMaskBlank;
                this.fBeepOnError = data.BeepOnError;
                this.fSaveLiteral = data.SaveLiteral;
                this.fMaskType = data.MaskType;
                this.fEditMask = data.EditMask;
                if (((data.Blank == null) || (data.Blank.Length == 0)) || (data.Blank == " "))
                {
                    this.fShowPlaceHolders = false;
                }
                else
                {
                    this.fShowPlaceHolders = true;
                    this.fPlaceHolder = data.Blank[0];
                }
            }
            finally
            {
                this.EndUpdate();
            }
        }

        public void Assign(MaskProperties data)
        {
            this.fSaveLiteral = data.SaveLiteral;
            this.fShowPlaceHolders = data.ShowPlaceHolders;
            this.fPlaceHolder = data.PlaceHolder;
            this.fEditMask = data.EditMask;
            this.fMaskType = data.MaskType;
            this.fIgnoreMaskBlank = data.IgnoreMaskBlank;
            this.fUseMaskAsDisplayFormat = data.UseMaskAsDisplayFormat;
            this.fBeepOnError = data.BeepOnError;
            this.fAutoComplete = data.AutoComplete;
            this.fCulture = data.fCulture;
            this.fAllowNullInput = new bool?(data.AllowNullInput);
            this.RaiseAfterChange();
        }

        public void BeginUpdate()
        {
            this.lockEvents++;
        }

        public MaskManager CreateDefaultMaskManager()
        {
            return CreateDefaultMaskManager(this);
        }

        private static MaskManager CreateDefaultMaskManager(MaskProperties mask)
        {
            CultureInfo culture = mask.Culture;
            if (culture == null)
            {
                culture = CultureInfo.CurrentCulture;
            }
            string editMask = mask.EditMask;
            if (editMask == null)
            {
                editMask = string.Empty;
            }
            switch (mask.MaskType)
            {

                case KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType.Numeric:
                    return new NumericMaskManager(editMask, culture, mask.AllowNullInput);

                //case KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType.RegEx:
                //    if (mask.IgnoreMaskBlank && (editMask.Length > 0))
                //    {
                //        editMask = "(" + editMask + ")?";
                //    }
                //    return new RegExpMaskManager(editMask, false, mask.AutoComplete != AutoCompleteType.None, mask.AutoComplete == AutoCompleteType.Optimistic, mask.ShowPlaceHolders, mask.PlaceHolder, culture);

                //case KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType.Regular:
                //    return new LegacyMaskManager(LegacyMaskInfo.GetRegularMaskInfo(editMask, culture), mask.PlaceHolder, mask.SaveLiteral, mask.IgnoreMaskBlank);

                //case KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType.Simple:
                //    return new LegacyMaskManager(LegacyMaskInfo.GetSimpleMaskInfo(editMask, culture), mask.PlaceHolder, mask.SaveLiteral, mask.IgnoreMaskBlank);
            }
            return null;
        }

        protected void DoBeforeChange(string name, object value)
        {
            if (this.BeforeChange != null)
            {
                ChangeEventArgs e = new ChangeEventArgs(name, value);
                this.BeforeChange(this, e);
            }
        }

        public void EndUpdate()
        {
            if (--this.lockEvents == 0)
            {
                this.RaiseAfterChange();
            }
        }

        public override bool Equals(object obj)
        {
            MaskProperties properties = obj as MaskProperties;
            if (properties == null)
            {
                return false;
            }
            if (this.MaskType != properties.MaskType)
            {
                return false;
            }
            if (this.EditMask != properties.EditMask)
            {
                return false;
            }
            if (this.AutoComplete != properties.AutoComplete)
            {
                return false;
            }
            if (this.BeepOnError != properties.BeepOnError)
            {
                return false;
            }
            if (this.ShowPlaceHolders != properties.ShowPlaceHolders)
            {
                return false;
            }
            if (this.PlaceHolder != properties.PlaceHolder)
            {
                return false;
            }
            if (this.IgnoreMaskBlank != properties.IgnoreMaskBlank)
            {
                return false;
            }
            if (this.AllowNullInput != properties.AllowNullInput)
            {
                return false;
            }
            if (this.UseMaskAsDisplayFormat != properties.UseMaskAsDisplayFormat)
            {
                return false;
            }
            if (this.SaveLiteral != properties.SaveLiteral)
            {
                return false;
            }
            if (!object.ReferenceEquals(this.Culture, properties.Culture))
            {
                return false;
            }
            return true;
        }

        public override int GetHashCode()
        {
            if (this.EditMask != null)
            {
                return this.EditMask.GetHashCode();
            }
            return 0;
        }

        protected void RaiseAfterChange()
        {
            if ((this.lockEvents == 0) && (this.AfterChange != null))
            {
                this.AfterChange(this, EventArgs.Empty);
            }
        }

        internal bool AllowNullInput
        {
            get
            {
               
                if (this.fAllowNullInput.HasValue)
                {
                    return this.fAllowNullInput.Value;
                }
                return this.IgnoreMaskBlank;
            }
            set
            {
                this.fAllowNullInput = new bool?(value);
            }
        }

        [Description("Gets or sets the automatic completion mode used by the editor in the RegEx mask mode."), Category("Mask"), DefaultValue(0), Localizable(true), RefreshProperties(RefreshProperties.All)]
        public virtual AutoCompleteType AutoComplete
        {
            get
            {
                return this.fAutoComplete;
            }
            set
            {
                if (this.AutoComplete != value)
                {
                    this.DoBeforeChange("AutoComplete", value);
                    this.fAutoComplete = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Description("Gets or sets whether an editor makes a beep sound when an end-user tries to enter an invalid character."), Category("Mask"), Localizable(true), DefaultValue(false)]
        public virtual bool BeepOnError
        {
            get
            {
                return this.fBeepOnError;
            }
            set
            {
                if (this.BeepOnError != value)
                {
                    this.DoBeforeChange("BeepOnError", value);
                    this.fBeepOnError = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Obsolete("Use PlaceHolder property instead"), Category("Mask"), DefaultValue("_"), Localizable(true), RefreshProperties(RefreshProperties.All), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual string Blank
        {
            get
            {
                if (!this.ShowPlaceHolders)
                {
                    return " ";
                }
                return this.PlaceHolder.ToString(CultureInfo.InvariantCulture);
            }
            set
            {
                if ((value == null) || (value.Length == 0))
                {
                    this.ShowPlaceHolders = false;
                }
                else
                {
                    this.ShowPlaceHolders = true;
                    this.PlaceHolder = value[0];
                }
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
        public CultureInfo Culture
        {
            get
            {
                return this.fCulture;
            }
            set
            {
                if (!object.ReferenceEquals(value, this.Culture))
                {
                    this.DoBeforeChange("Culture", value);
                    this.fCulture = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Description("Gets or sets a mask expression."), RefreshProperties(RefreshProperties.All), Category("Mask"), DefaultValue(""), Localizable(true)]
        public virtual string EditMask
        {
            get
            {
                return this.fEditMask;
            }
            set
            {
                if (this.EditMask != value)
                {
                    this.DoBeforeChange("EditMask", value);
                    this.fEditMask = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Localizable(true), Description("For the Simple, Regular and RegEx mask types this property gets or sets whether an editor can lose focus when a value hasn't been entered."), DefaultValue(true), Category("Mask")]
        public virtual bool IgnoreMaskBlank
        {
            get
            {
                return this.fIgnoreMaskBlank;
            }
            set
            {
                if (this.IgnoreMaskBlank != value)
                {
                    this.DoBeforeChange("IgnoreMaskBlank", value);
                    this.fIgnoreMaskBlank = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Description("Gets or sets the mask type."), RefreshProperties(RefreshProperties.All), DefaultValue(0), Category("Mask"), Localizable(true)]
        public virtual KP_CommonLibrary.KP_CommonControls.NumericInput.MaskType MaskType
        {
            get
            {
                return this.fMaskType;
            }
            set
            {
                if (this.fMaskType != value)
                {
                    this.DoBeforeChange("MaskType", value);
                    this.fMaskType = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Category("Mask"), Description("For the Simple, Regular and RegEx mask types this property gets or sets the character used as the placeholder in a masked editor."), RefreshProperties(RefreshProperties.All), DefaultValue('_'), Localizable(true)]
        public virtual char PlaceHolder
        {
            get
            {
                return this.fPlaceHolder;
            }
            set
            {
                if (value == '\0')
                {
                    value = '_';
                }
                if (this.fPlaceHolder != value)
                {
                    this.DoBeforeChange("PlaceHolder", value);
                    this.fPlaceHolder = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [RefreshProperties(RefreshProperties.All), Description("For the Simple and Regular mask types this property gets or sets whether constantly displayed mask characters (literals) are included in an editor's value. "), Category("Mask"), DefaultValue(true), Localizable(true)]
        public virtual bool SaveLiteral
        {
            get
            {
                return this.fSaveLiteral;
            }
            set
            {
                if (this.fSaveLiteral != value)
                {
                    this.DoBeforeChange("SaveLiteral", value);
                    this.fSaveLiteral = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Description("For the RegEx mask type this property gets or sets whether placeholders are displayed in a masked editor."), RefreshProperties(RefreshProperties.All), Category("Mask"), DefaultValue(true), Localizable(true)]
        public virtual bool ShowPlaceHolders
        {
            get
            {
                return this.fShowPlaceHolders;
            }
            set
            {
                if (this.ShowPlaceHolders != value)
                {
                    this.DoBeforeChange("ShowPlaceHolders", value);
                    this.fShowPlaceHolders = value;
                    this.RaiseAfterChange();
                }
            }
        }

        [Category("Mask"), Description("Gets or sets whether display values are still formatted using the mask when the editor is not focused."), DefaultValue(false), Localizable(true)]
        public virtual bool UseMaskAsDisplayFormat
        {
            get
            {
                return this.fUseMaskAsDisplayFormat;
            }
            set
            {
                if (this.UseMaskAsDisplayFormat != value)
                {
                    this.DoBeforeChange("UseMaskAsDisplayFormat", value);
                    this.fUseMaskAsDisplayFormat = value;
                    this.RaiseAfterChange();
                }
            }
        }
    }
}

